#!/bin/bash

# 维修计价助手系统自动部署脚本
# 适用于 Ubuntu/Debian Linux 系统
# 使用方法: chmod +x deploy.sh && ./deploy.sh

set -e  # 遇到错误立即退出

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查是否为 root 用户
check_root() {
    if [[ $EUID -eq 0 ]]; then
        log_error "请不要使用 root 用户运行此脚本"
        exit 1
    fi
}

# 检查系统类型
check_system() {
    log_info "检查系统类型..."
    if [[ -f /etc/debian_version ]]; then
        OS="debian"
        log_success "检测到 Debian/Ubuntu 系统"
    elif [[ -f /etc/redhat-release ]]; then
        OS="redhat"
        log_success "检测到 RedHat/CentOS 系统"
    else
        log_error "不支持的操作系统"
        exit 1
    fi
}

# 更新系统包
update_system() {
    log_info "更新系统包..."
    if [[ $OS == "debian" ]]; then
        sudo apt update && sudo apt upgrade -y
    elif [[ $OS == "redhat" ]]; then
        sudo yum update -y
    fi
    log_success "系统包更新完成"
}

# 安装基础依赖
install_dependencies() {
    log_info "安装基础依赖软件..."
    
    if [[ $OS == "debian" ]]; then
        sudo apt install -y curl wget git build-essential
    elif [[ $OS == "redhat" ]]; then
        sudo yum install -y curl wget git gcc gcc-c++ make
    fi
    
    log_success "基础依赖安装完成"
}

# 安装 Node.js
install_nodejs() {
    log_info "检查 Node.js 安装状态..."
    
    if command -v node &> /dev/null; then
        NODE_VERSION=$(node --version)
        log_info "已安装 Node.js 版本: $NODE_VERSION"
        
        # 检查版本是否满足要求 (v16+)
        MAJOR_VERSION=$(echo $NODE_VERSION | cut -d'.' -f1 | sed 's/v//')
        if [[ $MAJOR_VERSION -ge 16 ]]; then
            log_success "Node.js 版本满足要求"
            return
        else
            log_warning "Node.js 版本过低，需要升级"
        fi
    fi
    
    log_info "安装 Node.js 18.x..."
    
    if [[ $OS == "debian" ]]; then
        curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
        sudo apt-get install -y nodejs
    elif [[ $OS == "redhat" ]]; then
        curl -fsSL https://rpm.nodesource.com/setup_18.x | sudo bash -
        sudo yum install -y nodejs
    fi
    
    # 验证安装
    if command -v node &> /dev/null && command -v npm &> /dev/null; then
        log_success "Node.js 安装成功: $(node --version)"
        log_success "npm 版本: $(npm --version)"
    else
        log_error "Node.js 安装失败"
        exit 1
    fi
}

# 安装 PM2
install_pm2() {
    log_info "检查 PM2 安装状态..."
    
    if command -v pm2 &> /dev/null; then
        log_success "PM2 已安装: $(pm2 --version)"
        return
    fi
    
    log_info "安装 PM2..."
    sudo npm install -g pm2
    
    if command -v pm2 &> /dev/null; then
        log_success "PM2 安装成功: $(pm2 --version)"
    else
        log_error "PM2 安装失败"
        exit 1
    fi
}

# 检查项目目录
check_project_directory() {
    log_info "检查项目目录..."
    
    # 检查是否在项目根目录
    if [[ ! -f "package.json" ]]; then
        log_error "未找到 package.json 文件，请确保在项目根目录运行此脚本"
        exit 1
    fi
    
    if [[ ! -f "app.js" ]]; then
        log_error "未找到 app.js 文件，请确保在项目根目录运行此脚本"
        exit 1
    fi
    
    log_success "项目目录检查通过"
}

# 安装项目依赖
install_project_dependencies() {
    log_info "安装项目依赖..."
    
    # 检查 package.json 是否存在
    if [[ ! -f "package.json" ]]; then
        log_error "未找到 package.json 文件"
        exit 1
    fi
    
    # 安装依赖
    npm install
    
    # 验证关键依赖
    log_info "验证依赖安装..."
    npm list --depth=0
    
    log_success "项目依赖安装完成"
}

# 配置数据库
setup_database() {
    log_info "配置数据库..."
    
    # 检查数据库文件是否存在
    if [[ -f "database.db" ]]; then
        log_success "发现现有数据库文件，将保留现有数据"
        
        # 设置文件权限
        chmod 664 database.db
        log_info "已设置数据库文件权限"
    else
        log_warning "未找到数据库文件，应用启动时将自动创建"
    fi
    
    # 确保 uploads 目录存在
    mkdir -p uploads
    chmod 755 uploads
    log_info "已创建 uploads 目录"
    
    # 创建日志目录
    mkdir -p logs
    chmod 755 logs
    log_info "已创建 logs 目录"
}

# 创建环境配置
setup_environment() {
    log_info "创建环境配置..."
    
    # 创建 .env 文件
    cat > .env << EOF
NODE_ENV=production
PORT=3000
DB_PATH=./database.db
EOF
    
    log_success "环境配置文件创建完成"
}

# 配置防火墙
setup_firewall() {
    log_info "配置防火墙..."
    
    # 检查 ufw 是否安装
    if command -v ufw &> /dev/null; then
        echo -n "是否配置防火墙开放端口 3000? (Y/n): "
        read -r response
        if [[ "$response" =~ ^[Nn]$ ]]; then
            log_info "跳过防火墙配置"
            return
        fi
        
        sudo ufw allow 3000
        log_success "已开放端口 3000"
        
        echo -n "是否开放 HTTP/HTTPS 端口 (80/443)? (y/N): "
        read -r response
        if [[ "$response" =~ ^[Yy]$ ]]; then
            sudo ufw allow 80
            sudo ufw allow 443
            log_success "已开放端口 80 和 443"
        fi
        
        # 检查防火墙状态
        if sudo ufw status | grep -q "Status: inactive"; then
            echo -n "防火墙未启用，是否启用? (y/N): "
            read -r response
            if [[ "$response" =~ ^[Yy]$ ]]; then
                sudo ufw --force enable
                log_success "防火墙已启用"
            fi
        fi
    else
        log_warning "未检测到 ufw 防火墙，请手动配置防火墙规则"
    fi
}

# 创建 PM2 配置
setup_pm2_config() {
    log_info "创建 PM2 配置..."
    
    cat > ecosystem.config.js << EOF
module.exports = {
  apps: [{
    name: 'repair-system',
    script: 'app.js',
    instances: 1,
    autorestart: true,
    watch: false,
    max_memory_restart: '1G',
    env: {
      NODE_ENV: 'production',
      PORT: 3000
    },
    error_file: './logs/err.log',
    out_file: './logs/out.log',
    log_file: './logs/combined.log',
    time: true
  }]
};
EOF
    
    log_success "PM2 配置文件创建完成"
}

# 测试应用启动
test_application() {
    log_info "测试应用启动..."
    
    # 检查主应用文件是否存在
    if [[ ! -f "app.js" ]]; then
        log_error "未找到 app.js 文件"
        exit 1
    fi
    
    # 测试启动
    timeout 10s node app.js &
    APP_PID=$!
    sleep 3
    
    # 检查进程是否还在运行
    if kill -0 $APP_PID 2>/dev/null; then
        log_success "应用测试启动成功"
        kill $APP_PID
        wait $APP_PID 2>/dev/null
    else
        log_error "应用启动失败"
        exit 1
    fi
}

# 启动服务
start_service() {
    log_info "启动生产服务..."
    
    # 停止可能存在的服务
    pm2 stop repair-system 2>/dev/null || true
    pm2 delete repair-system 2>/dev/null || true
    
    # 启动服务
    pm2 start ecosystem.config.js
    
    # 等待服务启动
    sleep 3
    
    # 检查服务状态
    if pm2 list | grep -q "repair-system.*online"; then
        log_success "服务启动成功"
    else
        log_error "服务启动失败"
        pm2 logs repair-system --lines 20
        exit 1
    fi
}

# 设置开机自启
setup_autostart() {
    log_info "设置开机自启..."
    
    echo -n "是否设置开机自启? (Y/n): "
    read -r response
    if [[ "$response" =~ ^[Nn]$ ]]; then
        log_info "跳过开机自启设置"
        return
    fi
    
    # 生成启动脚本
    pm2 startup
    pm2 save
    
    log_success "开机自启设置完成"
}

# 验证部署
verify_deployment() {
    log_info "验证部署..."
    
    # 检查服务状态
    pm2 status
    
    # 检查端口监听
    if ss -tlnp | grep -q ":3000"; then
        log_success "端口 3000 正在监听"
    else
        log_error "端口 3000 未在监听"
        return 1
    fi
    
    # 测试 API
    sleep 2
    if curl -s http://localhost:3000/api/health > /dev/null; then
        log_success "API 健康检查通过"
    else
        log_warning "API 健康检查失败，请检查应用日志"
    fi
    
    # 显示访问信息
    SERVER_IP=$(hostname -I | awk '{print $1}')
    echo ""
    log_success "=== 部署完成 ==="
    echo -e "${GREEN}用户端访问地址:${NC} http://$SERVER_IP:3000/user.html"
    echo -e "${GREEN}管理端访问地址:${NC} http://$SERVER_IP:3000/admin.html"
    echo -e "${GREEN}API 健康检查:${NC} http://$SERVER_IP:3000/api/health"
    echo ""
    echo -e "${BLUE}常用命令:${NC}"
    echo "  查看服务状态: pm2 status"
    echo "  查看日志: pm2 logs repair-system"
    echo "  重启服务: pm2 restart repair-system"
    echo "  停止服务: pm2 stop repair-system"
    echo ""
}

# 主函数
main() {
    echo -e "${BLUE}"
    echo "======================================"
    echo "    维修计价助手系统自动部署脚本"
    echo "    (适用于已克隆的项目)"
    echo "======================================"
    echo -e "${NC}"
    
    # 执行部署步骤
    check_root
    check_system
    update_system
    install_dependencies
    install_nodejs
    install_pm2
    check_project_directory
    install_project_dependencies
    setup_database
    setup_environment
    setup_firewall
    setup_pm2_config
    test_application
    start_service
    setup_autostart
    verify_deployment
    
    log_success "自动部署完成！"
}

# 错误处理
trap 'log_error "部署过程中发生错误，请检查上面的错误信息"' ERR

# 运行主函数
main